# 游戏地图编辑器.py (带自动保存功能)
import pgzrun

# --- 编辑器常量 ---
TILE_SIZE = 40
GRID_WIDTH = 30
GRID_HEIGHT = 15
UI_PANEL_WIDTH = 200
WIDTH = GRID_WIDTH * TILE_SIZE + UI_PANEL_WIDTH
HEIGHT = GRID_HEIGHT * TILE_SIZE

# 自动保存参数 ---
AUTOSAVE_INTERVAL = 300 # 自动保存间隔（帧），300帧大约是5秒
autosave_timer = AUTOSAVE_INTERVAL

# --- 物件定义 ---
EMPTY_CHAR = '.'
PALETTE_ORDER = ['X', 'S', '?', 'C', 'E', 'P', 'F', EMPTY_CHAR]
PALETTE = {
    'X': 'brick', 'S': 'spring', '?': 'question_block', 'C': 'coin',
    'E': 'enemy_walk1', 'P': 'player_idle', 'F': 'flag', EMPTY_CHAR: 'eraser'
}

# --- 核心状态变量 ---
all_grids_data = []; current_level_index = 0; level_actors = []
# --- UI 元素 ---
selected_tile = 'X'; palette_items = {}; selection_box = Actor('selection_box')
ui_buttons = {
    'save': {'actor': Actor("save_button", topleft=(WIDTH - 180, HEIGHT - 180))},
    'add':  {'actor': Actor("add_button",  topleft=(WIDTH - 180, HEIGHT - 120))},
    'prev': {'actor': Actor("prev_button", topleft=(WIDTH - 180, HEIGHT - 60))},
    'next': {'actor': Actor("next_button", topleft=(WIDTH - 100, HEIGHT - 60))},
}
for name, data in ui_buttons.items():
    actor = data['actor']; data['bounds'] = (actor.left, actor.top, actor.width, actor.height)
message = ""; message_timer = 0

def create_empty_grid(): return [[EMPTY_CHAR for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]
def load_levels_from_file():
    global all_grids_data, current_level_index
    try:
        f=open('已保存关卡.py','r',encoding='utf-8'); lines=f.readlines(); f.close()
        print("找到 已保存关卡.py 文件，正在解析..."); parsed_levels=[]; current_level_rows=[]; is_parsing_level=False
        for line in lines:
            stripped_line = line.strip()
            if stripped_line.startswith('LEVEL_') and '=' in stripped_line and '[' in stripped_line:
                is_parsing_level=True; current_level_rows=[]; continue
            if is_parsing_level:
                if stripped_line == ']':
                    is_parsing_level=False
                    if current_level_rows: parsed_levels.append(current_level_rows)
                elif stripped_line.startswith('"') and (stripped_line.endswith('",') or stripped_line.endswith('"')):
                    content = stripped_line.strip(',')[1:-1].replace(' ', EMPTY_CHAR)
                    current_level_rows.append(content)
        if not parsed_levels: raise ValueError("在文件中未找到有效关卡数据。")
        all_grids_data.clear()
        for level_strings in parsed_levels:
            new_grid = create_empty_grid()
            for y, row_string in enumerate(level_strings):
                if y >= GRID_HEIGHT: break
                row_string = row_string.ljust(GRID_WIDTH, EMPTY_CHAR)
                for x, char in enumerate(row_string):
                    if x >= GRID_WIDTH: break
                    new_grid[y][x] = char
            all_grids_data.append(new_grid)
        print(f"成功从文件加载 {len(all_grids_data)} 个关卡！")
    except Exception as e:
        print(f"不存在 已保存关卡.py ({e})。将从一个空白关卡开始。"); all_grids_data=[create_empty_grid()]
    current_level_index=0; sync_actors_from_grid()
def sync_actors_from_grid():
    global level_actors; level_actors.clear()
    if not all_grids_data: return
    current_grid = all_grids_data[current_level_index]
    for y in range(GRID_HEIGHT):
        for x in range(GRID_WIDTH):
            char=current_grid[y][x]
            if char != EMPTY_CHAR and char in PALETTE:
                actor=Actor(PALETTE[char], topleft=(x * TILE_SIZE, y * TILE_SIZE)); level_actors.append(actor)
def setup_ui():
    start_y = 100; x_positions = [WIDTH - 150, WIDTH - 80]; y_pos = start_y; col_index = 0
    for char in PALETTE_ORDER:
        img_name = PALETTE[char]; actor = Actor(img_name)
        current_x = x_positions[col_index]; actor.pos = (current_x, y_pos)
        palette_items[char] = {'actor': actor, 'pos': actor.pos}
        col_index += 1
        if col_index >= len(x_positions): col_index = 0; y_pos += 70
    if selected_tile in palette_items: selection_box.pos = palette_items[selected_tile]['actor'].pos

def update():
    """_NEW_ 新增的 update 函数，用于处理自动保存计时器"""
    global autosave_timer
    autosave_timer -= 1
    if autosave_timer <= 0:
        save_all_levels(is_auto_save=True)
        autosave_timer = AUTOSAVE_INTERVAL # 重置计时器

def draw():
    global message_timer; screen.clear(); screen.fill("lightskyblue");
    for actor in level_actors: actor.draw()
    for x in range(0,GRID_WIDTH*TILE_SIZE,TILE_SIZE): screen.draw.line((x,0),(x,HEIGHT),'black')
    for y in range(0,HEIGHT,TILE_SIZE): screen.draw.line((0,y),(GRID_WIDTH*TILE_SIZE,y),'black')
    screen.draw.filled_rect(Rect((WIDTH-UI_PANEL_WIDTH,0),(UI_PANEL_WIDTH,HEIGHT)),"darkgrey")
    for item in palette_items.values(): item['actor'].draw()
    selection_box.draw()
    for data in ui_buttons.values(): data['actor'].draw()
    level_text = f"关卡: {current_level_index+1}/{len(all_grids_data)}"; screen.draw.text(level_text,(WIDTH-190,10),fontsize=28,color="white")
    if message_timer > 0: screen.draw.text(message,(WIDTH/2,20),fontsize=40,color="yellow",owidth=1,ocolor="black"); message_timer -= 1
def on_mouse_down(pos, button):
    global selected_tile
    mouse_x, mouse_y = pos
    if mouse_x > GRID_WIDTH * TILE_SIZE:
        for name, data in ui_buttons.items():
            bounds = data['bounds']
            if (bounds[0] <= mouse_x < bounds[0] + bounds[2] and bounds[1] <= mouse_y < bounds[1] + bounds[3]):
                handle_ui_click(name); return
        for char, item in palette_items.items():
            if item['actor'].collidepoint(pos):
                selected_tile = char; selection_box.pos = item['actor'].pos; return
    else:
        place_tile(pos, button)
def on_close():
    """_NEW_ 关闭窗口时的最后一道保险"""
    print("窗口关闭，正在进行最终保存...")
    save_all_levels()
    print("保存完毕。")

def handle_ui_click(b):
    if b=='save': save_all_levels()
    elif b=='prev': prev_level()
    elif b=='next': next_level()
    elif b=='add': add_new_level()
def prev_level(): 
    global current_level_index;
    if current_level_index>0: current_level_index-=1; sync_actors_from_grid()
def next_level(): 
    global current_level_index;
    if current_level_index < len(all_grids_data)-1: current_level_index+=1; sync_actors_from_grid()
def add_new_level(): 
    global current_level_index;
    all_grids_data.append(create_empty_grid()); current_level_index=len(all_grids_data)-1; sync_actors_from_grid()
def on_mouse_move(pos, buttons):
    if mouse.LEFT in buttons or 1 in buttons: place_tile(pos, mouse.LEFT)
    elif mouse.RIGHT in buttons or 3 in buttons: place_tile(pos, mouse.RIGHT)
def place_tile(pos, button):
    global autosave_timer # 只要有编辑操作，就重置自动保存计时器
    autosave_timer = AUTOSAVE_INTERVAL
    grid_x, grid_y = pos[0]//TILE_SIZE, pos[1]//TILE_SIZE
    if 0 <= grid_x < GRID_WIDTH and 0 <= grid_y < GRID_HEIGHT:
        grid=all_grids_data[current_level_index]; current=grid[grid_y][grid_x]
        new = selected_tile if button==mouse.LEFT else EMPTY_CHAR
        if current != new:
            if new == 'P': clear_char_from_grid('P')
            grid[grid_y][grid_x]=new; sync_actors_from_grid()
def clear_char_from_grid(char_to_clear):
    grid=all_grids_data[current_level_index]
    for r in range(GRID_HEIGHT):
        for c in range(GRID_WIDTH):
            if grid[r][c] == char_to_clear: grid[r][c] = EMPTY_CHAR
def save_all_levels(is_auto_save=False):
    global message, message_timer, autosave_timer
    file_content="# 由关卡编辑器自动生成\n\n"; level_names=[]
    for i, grid_data in enumerate(all_grids_data):
        level_name=f"LEVEL_{i+1}"; level_names.append(level_name)
        file_content+=f"# --- 第 {i+1} 关 ---\n"; file_content+=f"{level_name} = [\n"
        level_strings=["".join(row) for row in grid_data]
        for line in level_strings: file_content+=f'    "{line}",\n'
        file_content+="]\n\n"
    file_content+="# --- 关键：将所有关卡放入一个列表中 ---\n"; file_content+="ALL_LEVELS = [\n"
    for name in level_names: file_content+=f"    {name},\n"
    file_content+="]\n"
    try:
        f=open('已保存关卡.py','w',encoding='utf-8'); f.write(file_content); f.close()
        # 根据是手动保存还是自动保存，显示不同的消息
        if is_auto_save:
            message = "已自动保存！"
        else:
            message = f"全部 {len(all_grids_data)} 个关卡已保存！"
        autosave_timer = AUTOSAVE_INTERVAL # 保存成功后重置计时器
    except Exception as e:
        message=f"保存失败: {e}"
    message_timer = 120

load_levels_from_file()
setup_ui()
pgzrun.go()